--- title: Atmospheric Correction keywords: fastai sidebar: home_sidebar summary: "Out in the field, the OpenHSI camera measures light as it is reflected off surfaces. This light from the sun has absorption features from molecules/aerosols in the atmosphere and scattering. After converting the raw digital number counts into radiance" description: "Out in the field, the OpenHSI camera measures light as it is reflected off surfaces. This light from the sun has absorption features from molecules/aerosols in the atmosphere and scattering. After converting the raw digital number counts into radiance" nb_path: "03_atmos.ipynb" ---
{% raw %}
/Users/eway/.pyenv/versions/3.8.3/lib/python3.8/site-packages/pandas/compat/__init__.py:97: UserWarning: Could not import the lzma module. Your installed Python is incomplete. Attempting to use lzma compression will result in a RuntimeError.
  warnings.warn(msg)
/Users/eway/.pyenv/versions/3.8.3/lib/python3.8/site-packages/requests/__init__.py:89: RequestsDependencyWarning: urllib3 (1.26.7) or chardet (3.0.4) doesn't match a supported version!
  warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
{% endraw %} {% raw %}
{% endraw %} {% raw %}
{% endraw %}

Atmospheric Profile from Balloon Sounding

Find the closest station at http://weather.uwyo.edu/upperair/sounding.html to use the atmospheric sounding on the day. find the station number and region code (for example, south pacific is pac and new zealand is nz) Default is Willis Island in Queensland, Australia. https://py6s.readthedocs.io/en/latest/helpers.html#importing-atmospheric-profiles-from-radiosonde-data

Aerosol Profile from Aeronet

{% include warning.html content='Py6S states that custom aerosol profiles can be input but this is broken and there is no easy fix. Don’t waste a day trying... ' %}

{% raw %}

class Model6SV[source]

Model6SV()

{% endraw %} {% raw %}
{% endraw %}

Py6S provides a method to loop over an array and return the 6SV result. However, it does not have a progress bar. For something that can take several minutes, not knowing how long it will take is genuinely frustrating. Therefore, we provide a modified version of SixSHelpers.Wavelengths.run_wavelengths called Model6SV.run_wavelengths that has a progress bar.

To use 6SV, Py6S will write input files and parse the output files. All this I/O is slow but we got to deal with it. Py6S is clever about it though and uses threading to do some compute while waiting for files. The modified version follows the same method except with the addition of a callback to update the progress bar when interations are done.

{% raw %}

Model6SV.run_wavelengths[source]

Model6SV.run_wavelengths(wavelengths:array, n_threads:int=None)

Modified version of SixSHelpers.Wavelengths.run_wavelengths that has a progress bar. This implementation uses threading (through Python's multiprocessing API).

{% endraw %} {% raw %}
{% endraw %} {% raw %}
model = Model6SV(wavelength_array=np.arange(350, 1000, 10))
model.show()
100%|██████████| 65/65 [00:10<00:00,  6.23it/s]
{% endraw %}

Spectral Matcher

Used later for interactive empiriracl line calibration.

external

dc = DataCube() dc.load_nc("../load_multiple/2021-05-26 03_26_26.011211 radiance float32.nc") dc.show("bokeh",robust=True).opts(fontsize={'title': 15, 'labels': 14, 'xticks': 10, 'yticks': 10,})

{% raw %}
dc = DataCube()
dc.load_nc("../load_multiple/2021-05-26 03_26_26.011211 dn.nc")
dc.show("bokeh",robust=True)
{% endraw %} {% raw %}
model = Model6SV(wavelength_array=dc.binned_wavelengths)
model.show()
100%|██████████| 108/108 [00:17<00:00,  6.14it/s]
{% endraw %} {% raw %}

class SpectralMatcher[source]

SpectralMatcher(speclib_path, model_6SV:Model6SV)

Match OpenHSI spectra against USGS spectral library

{% endraw %} {% raw %}
{% endraw %} {% raw %}

remap[source]

remap(x, in_min, in_max, out_min, out_max)

{% endraw %} {% raw %}
{% endraw %} {% raw %}

SpectralMatcher.topk_spectra[source]

SpectralMatcher.topk_spectra(spectrum:array, k:int=5)

Match a spectrum against a spectral library spectra. Return the top k.

{% endraw %} {% raw %}
{% endraw %} {% raw %}
spec_matcher = SpectralMatcher(speclib_path="assets/speclib.pkl",model_6SV=model)
%time spec_matcher.topk_spectra(dc.dc.data[450,1500,:],5,refine=True)
CPU times: user 5.3 ms, sys: 286 µs, total: 5.59 ms
Wall time: 5.62 ms
label score
spectralon spectralon 0.935569
gray gray 0.885928
gray_small gray_small 0.868279
charcoal charcoal 0.834317
green_small green_small 0.657146
{% endraw %} {% raw %}
spec_matcher.show()
{% endraw %}

Interactive Widget

{% raw %}

class ELC[source]

ELC(nc_path:str) :: SpectralMatcher

Match OpenHSI spectra against USGS spectral library

{% endraw %} {% raw %}
{% endraw %} {% raw %}
elc = ELC(nc_path="../load_multiple/2021-05-26 03_26_26.011211 radiance float32.nc",speclib_path="assets/speclib.pkl",model_6SV=model)
elc()
{% endraw %} {% raw %}
plt.subplot(121); plt.plot(elc.a_ELC)
plt.subplot(122); plt.plot(elc.b_ELC)
[<matplotlib.lines.Line2D at 0x126f88c40>]
{% endraw %} {% raw %}
df = pd.read_pickle("assets/openhsi_radiance_select_targets.pkl")
df.plot(x='wavelength (nm)', y=df.columns[1:],figsize=(8,6),
          xlabel="wavelength (nm)",ylabel="radiance (uW/cm^2/sr/nm)",
          ylim=(0,None)).legend(loc="upper right",fontsize='xx-small')
<matplotlib.legend.Legend at 0x126680790>
{% endraw %} {% raw %}
speclib2 = elc.speclib.copy()
speclib2.rename(columns={"gray_small":"gray small","green_small":"green","cyan_small":"cyan","red_small":"magenta"},inplace=True)
name_dict = {"gray uni":"gray small","cyan uni":"cyan","green uni":"green",
             "magenta uni":"magenta","charcoal":"charcoal","gray":"gray","blue":"blue",
            "blue takeoff":"blue_take_off"}
name_dict2 = dict((v,k) for k,v in name_dict.items())
{% endraw %} {% raw %}
from datetime import datetime
model2 = Model6SV(wavelength_array=dc.binned_wavelengths,z_time=datetime.strptime("2021-05-26 03:26","%Y-%m-%d %H:%M"))
model2.show()
100%|██████████| 108/108 [00:16<00:00,  6.36it/s]
{% endraw %} {% raw %}
def get_3curves(df_col_name="blue"):
    
    #sim_df2 = spec_matcher_rad.topk_spectra(df[df_col_name],1)
    # LAB
    plot0 = hv.Curve(zip(df["wavelength (nm)"],speclib2[df_col_name]),label="Lab ASD").opts(
        fontsize={'title': 15, 'labels': 14, 'xticks': 10, 'yticks': 10,})
    
    # ELC
    spect = (np.array(df[name_dict2[df_col_name]]) - elc.b_ELC)/elc.a_ELC
    plot1 = hv.Curve(zip(df["wavelength (nm)"],spect),label="ELC estimate").opts(line_dash='dashed')
    
    # 6SV
    spect2 = np.array(df[name_dict2[df_col_name]])/model2.radiance*10
    plot2 = hv.Curve(zip(df["wavelength (nm)"],spect2),label="6SV estimate").opts(line_dash='dotted')
    
    # Modtran
    #plot3 = hv.Curve(zip(modtran_df["wavelength (nm)"],modtran_df[df_col_name]),label="Modtran")
    
    return (plot0 * plot1 * plot2 ).opts(xlabel="wavelength (nm)",ylabel="reflectance").opts(
        title=df_col_name,ylim=(0,1),legend_position='top_left').opts({'Curve': {'color': hv.Cycle('Dark2')}})

( get_3curves("gray") + get_3curves("charcoal") + get_3curves("blue") + \
get_3curves("green") + get_3curves("magenta") + get_3curves("cyan") ).cols(3)
{% endraw %}

Compare against USGS spectral library

{% raw %}
from pathlib import Path
{% endraw %} {% raw %}
@patch
def show(self:SpectralMatcher,is_ref:bool=False,ref_est:bool=False):
    if self.topk_idx is not None:
        hv_curves = []
        if not is_ref:
            hv_curves.append( hv.Curve(zip(self.wavelengths,self.last_spectra),label="tap point") )
        elif ref_est:
            hv_curves.append( hv.Curve(zip(self.wavelengths,self.last_spectra/(self.model_6SV.radiance/10)),label="6SV estimate") )
        for l in self.sim_df["label"]:
            alpha = self.sim_df[self.sim_df["label"]==l]["score"].to_numpy()
            alpha = 0.2 if len(alpha) == 0 else alpha[0]
            thresh = 0.94 if self.refine else 0.99
            alpha = 0.2 if alpha < thresh else 0.9
            temp = self.speclib_ref.copy() if is_ref else self.spectra.copy() 
            temp.insert(0,"wavelength",self.wavelengths)
            hv_curves.append( hv.Curve(temp,kdims="wavelength",vdims=l,label=l).opts(alpha=alpha) )
        return hv.Overlay(hv_curves).opts(width=1000, height=600,xlabel="wavelength (nm)",ylabel="reflectance")

    else:
        temp = self.speclib_ref.copy() if is_ref else self.spectra.copy() 
        temp.insert(0,"wavelength",self.wavelengths)
        curve_list = [hv.Curve(temp,kdims="wavelength",vdims=i,label=i) for i in temp.columns[1:] if (np.sum(temp[i]>1.)>0)]
        print(curve_list)
        if getattr(self,"last_spectra",None):
            return (hv.Overlay(curve_list)*hv.Curve(zip(self.wavelengths,self.last_spectra),label="last spectra")).opts(
                            width=1000, height=600,xlabel="wavelength (nm)",ylabel="reflectance",ylim=(0,1.1))
        return (hv.Overlay(curve_list)).opts(width=1000, height=600,xlabel="wavelength (nm)",ylabel="reflectance",ylim=(0,1.1))
{% endraw %} {% raw %}
@patch
def update_lib_folder(self:SpectralMatcher,directory,sort=False,save=False,show=True):
    fnames = sorted(os.listdir(directory))
    cwd = Path(directory)
    temp = None
    for f in fnames:
        if "ASD" not in f: continue
        if temp is None: 
            temp = pd.read_csv(cwd/f,delimiter="\t")
            temp.rename({temp.columns[0]:f[9:-9]}, axis='columns',inplace=True)
            temp.loc[~(temp[temp.columns[0]] > 0), temp.columns[0]]=np.nan
            
            
            if (np.sum(temp<0.)>0).to_numpy()[0]:
                breakpoint()
            #col_name = temp.columns[0]
            #temp.assign(col_name = lambda x: x.col_name.where(x.col_name.ge(0)))
        else: 
            buff = pd.read_csv(cwd/f,delimiter="\t")
            buff.loc[~(buff[buff.columns[0]] > 0), buff.columns[0]]=np.nan
            temp.insert(len(temp.columns),f[9:-9],buff[buff.columns[0]])
    self.orig_speclib = pd.concat([self.orig_speclib,temp[temp.columns[1:]]],axis=1)
    self.orig_speclib = self.orig_speclib.loc[:,~self.orig_speclib.columns.duplicated()]
    print(f"Added folder of ASD spectra to spectral library")
    self._interp()
    return self._sort_save_show(sort,save,show)
{% endraw %} {% raw %}
%%time
spec_matcher = SpectralMatcher(speclib_path="assets/speclib.pkl",model_6SV=model)
spec_matcher.update_lib_folder("../../Downloads/ASCIIdata_splib07b/ChapterV_Vegetation/")
spec_matcher.show(is_ref=True).opts(tools=["hover"])
Added folder of ASD spectra to spectral library
[:Curve   [wavelength]   (spectralon), :Curve   [wavelength]   (Cactus_Opuntia-1_purple_pad_ASDFRa), :Curve   [wavelength]   (P.australis_CRMS-0153_dryNPV_ASDFRa)]
[:Curve   [wavelength]   (spectralon), :Curve   [wavelength]   (Cactus_Opuntia-1_purple_pad_ASDFRa), :Curve   [wavelength]   (P.australis_CRMS-0153_dryNPV_ASDFRa)]
CPU times: user 822 ms, sys: 70.1 ms, total: 892 ms
Wall time: 992 ms
{% endraw %} {% raw %}
spec_matcher.orig_speclib["Cactus_Opuntia-1_purple_pad_ASDFRa"].plot()
<matplotlib.axes._subplots.AxesSubplot at 0x131992100>
{% endraw %} {% raw %}
spec_matcher.orig_speclib["Walnut_Leaf_SUN_(Green)_BECKa"]
0            NaN
1            NaN
2            NaN
3            NaN
4            NaN
          ...   
2146    0.501375
2147    0.500840
2148    0.500333
2149    0.499831
2150    0.499330
Name: Walnut_Leaf_SUN_(Green)_BECKa, Length: 2151, dtype: float64
{% endraw %} {% raw %}
spec_matcher.orig_speclib[["wavelength",'Walnut_Leaf_SUN_(Green)_BECKa']].plot(x="wavelength",xlim=(350,2500))
<matplotlib.axes._subplots.AxesSubplot at 0x131716fa0>
{% endraw %} {% raw %}
@patch
def _interp(self):
    # interpolate the spectral library to the OpenHSI wavelengths
    self.speclib = self.orig_speclib.copy()
    self.speclib.insert(0,"type","USGS")
    self.speclib = pd.concat( [ pd.DataFrame({"type":"openhsi","wavelength":self.wavelengths}), self.speclib] )
    self.speclib.set_index("wavelength",inplace=True)
    self.speclib.interpolate(method="cubicspline",axis="index",limit_direction="both",inplace=True)
    self.speclib = self.speclib[self.speclib["type"].str.match("openhsi")]
    self.speclib.drop("type", 1,inplace=True)
    self.speclib_ref = self.speclib.copy()
    self.spectra = (self.speclib[:].T*self.model_6SV.radiance/10).T
    self.spectra_norm = norm(self.spectra,axis=0)
{% endraw %} {% raw %}
speclib = spec_matcher.orig_speclib[["wavelength","Walnut_Leaf_SUN_(Green)_BECKa"]]
speclib.insert(0,"type","USGS") # insert column in 0th index with label "type" and value "USGS"
speclib = pd.concat( [ pd.DataFrame({"type":"openhsi","wavelength":spec_matcher.wavelengths}), speclib] )
speclib.set_index("wavelength",inplace=True)

speclib.tail(2000)
<matplotlib.axes._subplots.AxesSubplot at 0x1315f90d0>
{% endraw %} {% raw %}
print(spec_matcher.orig_speclib.columns.to_numpy())
['wavelength' 'spectralon' 'gray_small' 'green_small' 'red_small'
 'cyan_small' 'gray' 'charcoal' 'blue' 'blue_take_off'
 'Antigorite+.33DryGrass_AMX25_ASDFRa' 'Aspen_Aspen-1_green-top_ASDFRa'
 'Aspen_Aspen-2_green-bottom_ASDFRa' 'Aspen_Aspen-3_yellowGreenTop_ASDFRa'
 'Aspen_Aspen-4_yellow-top_ASDFRa' 'Aspen_Leaf-A_DW92-2_BECKa'
 'Aspen_Leaf-B_DW92-3_BECKa' 'Aspen_YNP-AS-1_forest_AVIRISb'
 'Bacterial_mat_YNP-B1_AVIRISb' 'Blackbrush_ANP92-9A_leaves_BECKa'
 'Blue_Spruce_DW92-5_needles_BECKa' 'Buckbrush_CA01-CECU-1_bush_1_ASDFRa'
 'Buckbrush_CA01-CECU-2_bush_2_ASDFRa'
 'Buckbrush_CA01-CECU-3_bush_3_ASDFRa'
 'Cactus_Opuntia-1_purple_pad_ASDFRa' 'Cattail_YNP-CT-1_AVIRISb'
 'Chamise_CA01-ADFA-1_bush_1_ASDFRa' 'Chamise_CA01-ADFA-2_bush_2_ASDFRa'
 'Cheatgrass_ANP92-11A_BECKa' 'Cheatgrass_ANPC1_field_calib_ASDFRa'
 'Conifer-Meadow-Mix_YNP-CM-1_AVIRISb'
 'D.spicata_DWV6-0511_dryNPV.a_ASDFRa'
 'Douglas-Fir_YNP-DF-1_forest_AVIRISb'
 'Douglas-Fir_YNP-DF-2_forest_AVIRISb'
 'Douglas-Fir_YNP-DF-3_forest_AVIRISb'
 'Engelmann-Spruce_ES-Needls-1_ASDFRa'
 'Espruce-Sfir_YNP-SF-1_forst_AVIRISb'
 'Espruce-Sfir_YNP-SF-2_forst_AVIRISb'
 'Espruce-Sfir_YNP-SF-3_forst_AVIRISb'
 'Espruce-Sfir_YNP-SF-4_forst_AVIRISb'
 'Espruce-Sfir_YNP-SF-5_forst_AVIRISb'
 'Flower_Geranium-1_Red-Orange_ASDFRa' 'Flower_Pansy-1_Yellow_ASDFRa'
 'Flower_Petunia-1_Pink_ASDFRa' 'Flower_Petunia-2_Purple_ASDFRa'
 'Flower_Petunia-3_White_ASDFRa' 'Flower_Platycodon-1_Purple_ASDFRa'
 'Flower_Platycodon-2_White_ASDFRa' 'Grass-FescueNeedlg_YNP-FN-1_AVIRISb'
 'Grass-FescueWheatg_YNP-FW-1_AVIRISb'
 'Grass-FescueWheatg_YNP-FW-2_AVIRISb'
 'Grass-FescueWheatg_YNP-FW-3_AVIRISb'
 'Grass-Smoothbrome_YNP-SB-1_AVIRISb'
 'Grass_AETR70_CA01-AETR-2_NPV_ASDFRa'
 'Grass_AETR95_CA01-AETR-1_NPV_ASDFRa'
 'Grass_CA01-TACA-1_meadow_NPV_ASDFRa' 'Grass_Golden_Dry_GDS480_ASDFRa'
 'Grass_dry.4+.6green_AMX27_BECKa' 'Grass_dry.5+.5green_AMX28_BECKa'
 'Grass_dry.6+.4green_AMX29_BECKa' 'Grass_dry.7+.3green_AMX30_BECKa'
 'Grass_dry.8+.2green_AMX31_BECKa' 'Grass_dry.83+.17NaMont_AMX35_BECKb'
 'Grass_dry.9+.1green_AMX32_BECKa' 'Gray-Pine_CA01-PISA-1_branch_ASDFRa'
 'Gray-Pine_CA01-PISA-2_branch_ASDFRa'
 'Gray-Pine_CA01-PISA-3_needls_ASDFRa'
 'Hyacinth_DWO-3-DEL-2_leaf.a_ASDFRa' 'J.roemer._DWV1-0511a_gr.a_ASDFRa'
 'J.roemer._DWV1-0511b_dkgrn.a_ASDFRa'
 'J.roemer._DWV1-0511c_grbrn.a_ASDFRa' 'J.roemer._DWV1-0511d_NPV.a_ASDFRa'
 'J.roemer._DWV6a2-0511_NPV.a_ASDFRa' 'Juniper_IH91-4B_BECKa'
 'LawnGrass_GDS91b_+1shf-unshf_BECKa' 'LawnGrass_GDS91b_+1shft_3nm_BECKa'
 'LawnGrass_GDS91b_+const_1.0_BECKa' 'LawnGrass_GDS91b_-shiftd_3nm_BECKa'
 'LawnGrass_GDS91b_shifted_3nm_BECKa' 'Lawn_Grass_GDS91_green_BECKa'
 'LeafySpurge_Spurge-A1-Jul98_ASDFRa' 'LeafySpurge_Spurge-A1-Jun98_ASDFRa'
 'LeafySpurge_Spurge-A1-Oct97_ASDFRa' 'LeafySpurge_Spurge-A1-Sep97_ASDFRa'
 'LeafySpurge_Spurge-A2-Jun98_ASDFRa' 'LeafySpurge_Spurge-B1-Jul98_ASDFRa'
 'LeafySpurge_Spurge-B1-Oct97_ASDFRa' 'LeafySpurge_Spurge-B2-Jul98_ASDFRa'
 'LeafySpurge_Spurge-B3-Jul98_ASDFRa' 'LeafySpurge_Spurge-C1-Oct97_ASDFRa'
 'Lichen_Acarospora-1_ASDFRb' 'Lichen_Licedea-1_ASDFRb'
 'Lichen_Licedea-2_ASDFRb' 'Lichen_Xanthoparmelia-1_ASDFRb'
 'Lichen_Xanthoparmelia-2_ASDFRb' 'Lichen_Xanthoria-1_ASDFRb'
 'Lodgepole-Pine_LP-Needles-1_ASDFRa' 'Lodgepole-Pine_LP-Needles-2_ASDFRa'
 'Lodgepole-Pine_LP-Needles-3_ASDFRa' 'Lodgepole-Pine_YNP-LP0-MOD_AVIRISb'
 'Lodgepole-Pine_YNP-LP0-VIG_AVIRISb' 'Lodgepole-Pine_YNP-LP1-A_AVIRISb'
 'Lodgepole-Pine_YNP-LP1-B_AVIRISb' 'Lodgepole-Pine_YNP-LP1-C_AVIRISb'
 'Lodgepole-Pine_YNP-LP1-D_AVIRISb' 'Lodgepole-Pine_YNP-LP2-A_AVIRISb'
 'Lodgepole-Pine_YNP-LP2-B_AVIRISb' 'Lodgepole-Pine_YNP-LP3-A_AVIRISb'
 'Lodgepole-Pine_YNP-LP3-B_AVIRISb' 'Lodgepole-Pine_YNP-LP_AVIRISb'
 'Lythr.lineare_CRMS326v59_grn_ASDFRa'
 'Manzanita_CA01-ARVI-1_bush_1_ASDFRa'
 'Manzanita_CA01-ARVI-2_bush_2_ASDFRa'
 'Manzanita_CA01-ARVI-3_bush_3_ASDFRa'
 'Manzanita_CA01-ARVI-4_bush_4_ASDFRa'
 'Manzanita_CA01-ARVI-5_bush_5_ASDFRa'
 'Manzanita_CA01-ARVI-6_bush_6_ASDFRa'
 'Manzanita_CA01-ARVI-7_leaves_ASDFRa' 'Maple_Leaves_DW92-1_BECKa'
 'MarshWater_CRMS121v69-NoGlnt_ASDFRa'
 'Marsh_DISP60%...._CRMS326v59_ASDFRa'
 'Marsh_DISP65%...a_CRMS326v84_ASDFRa'
 'Marsh_DISP80%..._CRMS326v64_ASDFRa' 'Marsh_PHAU_100%_DWO-3-DEL-2_ASDFRa'
 'Marsh_SCAM-DISP..CRMS326v48a_ASDFRa'
 'Marsh_SCAM-DISP..CRMS326v50a_ASDFRa'
 'Marsh_SCAM-DISP..CRMS326v71a_ASDFRa'
 'Marsh_SCAM42%...._CRMS326v50_ASDFRa'
 'Marsh_SCAM45%..._CRMS121v28_ASDFRa'
 'Marsh_SCAM50%...._CRMS326v48_ASDFRa'
 'Marsh_SCAM50%..._CRMS121v32_ASDFRa'
 'Marsh_SCAM60%...._CRMS326v71_ASDFRa'
 'Marsh_SCAM66%..._CRMS121v38_ASDFRa' 'Marsh_SCAM71%..._CRMS121v49_ASDFRa'
 'Marsh_SCAM72%..._CRMS121v33_ASDFRa' 'Marsh_SCAM77%..._CRMS121v34_ASDFRa'
 'Marsh_SCAM81%..._CRMS121v37_ASDFRa' 'Marsh_SPAL50%..._CRMS322v52_ASDFRa'
 'Marsh_SPAL50%...a_CRMS322v52_ASDFRa'
 'Marsh_SPAL55%...a_CRMS322v25_ASDFRa'
 'Marsh_SPAL60%...a_CRMS322v55_ASDFRa'
 'Marsh_SPAL70%...a_CRMS322v16_ASDFRa'
 'Marsh_SPAL70%...a_CRMS322v79_ASDFRa'
 'Marsh_SPAL77%..._CRMS322v83_ASDFRa'
 'Marsh_SPAL80%...a_CRMS322v06_ASDFRa'
 'Marsh_SPAL92%...a_CRMS322v78_ASDFRa'
 'Marsh_SPAL95%...a_CRMS322v68_ASDFRa'
 'Marsh_SPPA35%...a_CRMS326v81_ASDFRa'
 'Marsh_SPPA49%...a_CRMS326v06_ASDFRa'
 'Marsh_SPPA55%...a_CRMS326v02_ASDFRa'
 'Marsh_SPPA67%...a_CRMS326v10_ASDFRa'
 'Marsh_sediment_DWV3-0511_dry_ASDFRa'
 'Marsh_water40%..._CRMS121v69_ASDFRa'
 'Marsh_water55%..._CRMS121v47_ASDFRa'
 'Marsh_water75%..._CRMS322v84_ASDFRa'
 'Marsh_water80%..._CRMS121v23_ASDFRa'
 'Marsh_water_CRMS121v69-glint_ASDFRa'
 'Marsh_water_CRMS322v84a_sunl_ASDFRa'
 'Marsh_wrack_DWV1-0511_NPV.a_ASDFRa'
 'Marsh_wrack_DWV3-0511_dryNPV_ASDFRa' 'Oak_Oak-Leaf-1_fresh_ASDFRa'
 'Oak_Oak-Leaf-2_dried_ASDFRa' 'Oak_QUDU_CA01-QUDU-1_bush_1_ASDFRa'
 'Oak_QUDU_CA01-QUDU-2_bush_2_ASDFRa' 'Oak_QUDU_CA01-QUDU-3_bush_3_ASDFRa'
 'P.aus._DWO-3-DEL-2d_dryNPV.a_ASDFRa'
 'P.austr._DWO-3-DEL-2a_stems_ASDFRa' 'P.austr._DWO-3-DEL-2b_grn.a_ASDFRa'
 'P.austr._DWO-3-DEL-2c_stem.a_ASDFRa'
 'P.australis_CRMS-0153_dryNPV_ASDFRa' 'Pinon_Pine_ANP92-14A_needle_BECKa'
 'Rabbitbrush_ANP92-27_BECKa' 'Rangeland_C03-004_S08%_G27%_ASDFRa'
 'Rangeland_C03-005_S25%_G24%_ASDFRa' 'Rangeland_C03-006_S01%_G39%_ASDFRa'
 'Rangeland_C03-010_S12%_G15%_ASDFRa' 'Rangeland_C03-013_S06%_G08%_ASDFRa'
 'Rangeland_C03-014_S26%_G25%_ASDFRa' 'Rangeland_C03-017_S20%_G19%_ASDFRa'
 'Rangeland_C03-019_S20%_G14%_ASDFRa' 'Rangeland_C03-021_S11%_G07%_ASDFRa'
 'Rangeland_C03-022_S12%_G22%_ASDFRa' 'Rangeland_C03-027_S27%_G19%_ASDFRa'
 'Rangeland_C03-031_S15%_G14%_ASDFRa' 'Rangeland_C03-032_S34%_G15%_ASDFRa'
 'Rangeland_C03-037_S37%_G13%_ASDFRa' 'Rangeland_C03-041_S15%_G06%_ASDFRa'
 'Rangeland_C03-047_S09%_G12%_ASDFRa' 'Rangeland_C03-050_S18%_G12%_ASDFRa'
 'Rangeland_C03-052_S22%_G24%_ASDFRa' 'Rangeland_C03-066_S11%_G17%_ASDFRa'
 'Rangeland_C03-068_S05%_G43%_ASDFRa' 'Rangeland_C03-070_S02%_G31%_ASDFRa'
 'Rangeland_C03-073_S30%_G24%_ASDFRa' 'Rangeland_C03-074_S24%_G16%_ASDFRa'
 'Rangeland_C03-076_S13%_G13%_ASDFRa' 'Rangeland_C03-077_S09%_G10%_ASDFRa'
 'Rangeland_C03-080_S18%_G15%_ASDFRa' 'Rangeland_C03-081_S07%_G23%_ASDFRa'
 'Rangeland_C03-085_S06%_G24%_ASDFRa' 'Rangeland_C03-086_S29%_G13%_ASDFRa'
 'Rangeland_C03-089_S20%_G21%_ASDFRa' 'Rangeland_C03-090_S14%_G31%_ASDFRa'
 'Rangeland_C03-091_S30%_G17%_ASDFRa' 'Rangeland_C03-095_S09%_G08%_ASDFRa'
 'Rangeland_C03-097_S07%_G21%_ASDFRa' 'Rangeland_C04-151_S29%_G05%_ASDFRa'
 'Rangeland_C04-153_S12%_G16%_ASDFRa' 'Rangeland_C04-154_S12%_G10%_ASDFRa'
 'Rangeland_C04-155A_S03%_G38%_ASDFRa'
 'Rangeland_C04-166_S09%_G10%_ASDFRa' 'Rangeland_C04-170_S30%_G24%_ASDFRa'
 'Rangeland_C04-175_S06%_G23%_ASDFRa' 'Rangeland_C04-197_S17%_G15%_ASDFRa'
 'Rangeland_C04-200_S03%_G17%_ASDFRa' 'Rangeland_C04-203_S21%_G07%_ASDFRa'
 'Rangeland_C04-204_S24%_G06%_ASDFRa' 'Rangeland_C04-208_S15%_G20%_ASDFRa'
 'Rangeland_C04-209A_S17%_G04%_ASDFRa'
 'Rangeland_C04-211_S03%_G16%_ASDFRa' 'Rangeland_C04-214_S03%_G17%_ASDFRa'
 'Rangeland_C04-226_S05%_G25%_ASDFRa' 'Rangeland_C04-232_S23%_G13%_ASDFRa'
 'Rangeland_C04-233_S16%_G06%_ASDFRa' 'Rangeland_C04-236_S20%_G18%_ASDFRa'
 'Rangeland_C04-237_S05%_G25%_ASDFRa' 'Rangeland_C04-243A_S05%G02%_ASDFRa'
 'Rangeland_C04-251_S17%_G07%_ASDFRa' 'Rangeland_C04-252_S08%_G05%_ASDFRa'
 'Rangeland_C04-253_S27%_G21%_ASDFRa' 'Rangeland_C04-264_S09%_G18%_ASDFRa'
 'Rangeland_C04-272_S04%_G36%_ASDFRa' 'Rangeland_C04-273_S25%_G08%_ASDFRa'
 'Rangeland_C04-288_S19%_G34%_ASDFRa' 'Rangeland_C04-295_S17%_G17%_ASDFRa'
 'Rangeland_L02-005_S14%_G16%_ASDFRa' 'Rangeland_L02-013_S00%_G31%_ASDFRa'
 'Rangeland_L02-015_S01%_G35%_ASDFRa' 'Rangeland_L02-019_S01%_G06%_ASDFRa'
 'Rangeland_L02-022_S20%_G09%_ASDFRa' 'Rangeland_L02-023_S01%_G56%_ASDFRa'
 'Rangeland_L02-025_S00%_G21%_ASDFRa' 'Rangeland_L02-042_S01%_G57%_ASDFRa'
 'Rangeland_L02-043_S01%_G07%_ASDFRa' 'Rangeland_L02-045_S01%_G04%_ASDFRa'
 'Rangeland_L02-046_S16%_G20%_ASDFRa' 'Rangeland_L02-054_S00%_G21%_ASDFRa'
 'Rangeland_L02-057_S01%_G47%_ASDFRa' 'Rangeland_L02-058_S00%_G25%_ASDFRa'
 'Rangeland_L02-060_S00%_G13%_ASDFRa' 'Rangeland_L02-061_S00%_G06%_ASDFRa'
 'Rangeland_L02-068A_S00%_G38%_ASDFRa'
 'Rangeland_L02-069_S00%_G99%_ASDFRa' 'Rangeland_L02-077_S00%_G28%_ASDFRa'
 'Rangeland_L04-035_S03%_G54%_ASDFRa' 'Rangeland_L04-047_S00%_G47%_ASDFRa'
 'Rangeland_L04-058_S34%_G25%_ASDFRa' 'Rangeland_L04-072_S30%_G21%_ASDFRa'
 'Rangeland_L04-075A_S00%_G49%_ASDFRa'
 'Rangeland_L04-091_S10%_G11%_ASDFRa' 'Rangeland_L04-095_S01%_G51%_ASDFRa'
 'Rangeland_L04-096_S00%_G45%_ASDFRa' 'Russian_Olive_DW92-4_BECKa'
 'S.altern._DWV1-0511_NPV.a_ASDFRa' 'S.altern._DWV6a2-0511_stem.a_ASDFRa'
 'S.altern._DWV6a4-0511_gray.a_ASDFRa'
 'S.altern._DWV6b3-0511_NPV.a_ASDFRa'
 'S.alternif._CRMS322v06_grn.a_ASDFRa' 'S.alterniflora_CRMS322_NPV_ASDFRa'
 'S.america._CRMS121v38_yellow_ASDFRa'
 'S.americanus_CRMS326v06_gr.a_ASDFRa' 'Sagebrush_IH91-1B_BECKa'
 'Sagebrush_Sage-Leaves-1_dry_ASDFRa' 'Sagebrush_YNP-SS-1_AVIRISb'
 'Sagebrush_YNP-SS-2_AVIRISb' 'Sagebrush_YNP-SS-3_AVIRISb'
 'Sagebrush_YNP-SS-4_AVIRISb' 'Saltbrush_ANP92-31A_BECKa'
 'Sedge_YNP-SE-1_AVIRISb' 'Spar.patens_CRMS322v06_grn.a_ASDFRa'
 'Stonwll_Ply+.1grnGrass_AMX33_BECKa' 'Stonwll_Ply+.2grnGrass_AMX34_BECKa'
 'Toyon_CA01-HEAR-1_bush_ASDFRa' 'Tumbleweed_ANP92-2C_Dry_BECKa'
 'Walnut_Leaf_SUN_(Green)_BECKa' 'Wetland_YNP-WT-1_AVIRISb'
 'Wetland_YNP-WT-2_AVIRISb' 'WhitebarkPine_YNP-WB-1_frst_AVIRISb'
 'WhitebarkPine_YNP-WB-2_frst_AVIRISb' 'Willow-Sedge-Mix_YNP-WS-1_AVIRISb'
 'Willow_Dead_FluvTailSite_A_ASDFRa' 'Willow_Willow-Leaves-1_dry_ASDFRa'
 'Willow_YNP-WI-1_AVIRISb' 'Yerba_Santa_CA01-ERCA-1_bush_ASDFRa'
 'Yerba_Santa_CA01-ERCA-2_bush_ASDFRa']
{% endraw %}